package com.bwie.service.Impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bwie.utils.KaptchaUtils;
import com.bwie.utils.MobileMessageUtil;
import com.bwie.utils.R;
import com.bwie.vo.LoginFromVo;
import com.bwie.vo.SendPhoneCodeVo;
import com.github.tobato.fastdfs.domain.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bwie.pojo.User;
import com.bwie.mapper.UserMapper;
import com.bwie.service.UserService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;

@Service
@Transactional
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService{
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private HttpServletResponse response;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private FastFileStorageClient fileStorageClient;
    @Override
    public void imageCode() {
        //生成随机数4位
        String imageCode = RandomUtil.randomNumbers(4);
        String StringKey = "imageCode";
        //生成验证码
        KaptchaUtils.generateCaptcha(response,imageCode);
        //验证码放入缓存
        redisTemplate.opsForValue().set(StringKey,imageCode,1, TimeUnit.MINUTES);
    }

    @Override
    public R sendPhoneCode(SendPhoneCodeVo sendPhoneCodeVo) {
        //限定60秒只能发送一次验证码
        String sendKey = "send-phoneCode";
        Boolean b = redisTemplate.hasKey(sendKey);
        if(b){
            return R.ERROR(500,"请勿频繁发送验证码");
        }
        //图片验证码是否正确或者过期
        String imageCodeKey = "imageCode";
        String imageCode = redisTemplate.opsForValue().get(imageCodeKey);
        if(StringUtils.isEmpty(imageCode)){
            return R.ERROR(500,"图形验证码已过期");
        }
        if(!imageCode.equalsIgnoreCase(sendPhoneCodeVo.getImageCode())){
            return R.ERROR(500,"图形验证码错误");
        }
        //手机号是否存在
        User user = userMapper.selectOne(
                new QueryWrapper<User>().lambda().eq(User::getUserPhone, sendPhoneCodeVo.getPhone())
        );
        if(ObjectUtils.isEmpty(user)){
            return R.ERROR(500,"手机号不存在");
        }
        //发送手机验证码
        String phoneCode = RandomUtil.randomNumbers(4);
        MobileMessageUtil.sendMobileMessage(sendPhoneCodeVo.getPhone(),phoneCode);
        //验证码存在缓存5分钟
        String phoneCodeKey = "phoneCode";
        redisTemplate.opsForValue().set(phoneCodeKey,phoneCode,5,TimeUnit.MINUTES);
        //限定60秒只能发送一次
        String sendPhoneCode = "send-phoneCode";
        redisTemplate.opsForValue().set(sendPhoneCode,phoneCode,60,TimeUnit.SECONDS);
        return R.OK();
    }

    @Override
    public R login(LoginFromVo loginFromVo) {
        //手机号是否存在
        User user = userMapper.selectOne(
                new QueryWrapper<User>().lambda().eq(User::getUserPhone, loginFromVo.getPhone())
        );
        if(ObjectUtils.isEmpty(user)){
            return R.ERROR(500,"手机号不存在");
        }
        //短信验证码验证
        String PhoneCodeKey = "phoneCode";
        String redisPhoneCode = redisTemplate.opsForValue().get(PhoneCodeKey);
        if(StringUtils.isEmpty(redisPhoneCode)){
            return R.ERROR(500,"验证码已过期");
        }
        if(!redisPhoneCode.equals(loginFromVo.getPhoneCode())){
            return R.ERROR(500,"验证码错误");
        }
        //生成token
        String token = Jwts.builder().signWith(SignatureAlgorithm.HS256, "123456")
                .claim("id", user.getId()).compact();
        //放入缓存
        String tokenKey = "token-"+user.getId();
        redisTemplate.opsForValue().set(tokenKey,token,15,TimeUnit.MINUTES);
        user.setToken(token);
        user.setPassword(null);
        return R.OK(user);
    }

    @Override
    public R uploadFile(MultipartFile file) {
        //获取名字
        String extedName = FileUtil.extName(file.getOriginalFilename());
        try {
            StorePath storePath = fileStorageClient.uploadFile(file.getInputStream(), file.getSize(), extedName, null);
            String path = "http://192.168.80.192:8888/"+storePath.getFullPath();
            return R.OK(path);
        } catch (IOException e) {
            e.printStackTrace();
            return R.ERROR(500,"上传失败");
        }
    }
}
